Android进阶5:SurfaceView实现原理分析 您所在的位置:网站首页 surface go 3尺寸 Android进阶5:SurfaceView实现原理分析

Android进阶5:SurfaceView实现原理分析

#Android进阶5:SurfaceView实现原理分析| 来源: 网络整理| 查看: 265

public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallback {

    //OtherCodes

   final ArrayList mCallbacks            = new ArrayList();//重要的回调集合

    final int[] mLocation = new int[2];

    final ReentrantLock mSurfaceLock = new ReentrantLock();    // Current surface in use    final Surface mSurface = new Surface();       

    //OtherCodes

     /**     * Return the SurfaceHolder providing access and control over this     * SurfaceView's underlying surface.     *     * @return SurfaceHolder The holder of the surface.     */     //获取当前持有的holder    public SurfaceHolder getHolder() {        return mSurfaceHolder;    }

    //surfaceView持有mSurfaceHolder的final类。对上面的surface进行管理

    private final SurfaceHolder mSurfaceHolder = new SurfaceHolder() {        private static final String LOG_TAG = "SurfaceHolder";

        @Override        public boolean isCreating() {            return mIsCreating;        }

         //把holder.callback添加到上面回调集合        @Override        public void addCallback(Callback callback) {            synchronized (mCallbacks) {                // This is a linear search, but in practice we'll                // have only a couple callbacks, so it doesn't matter.                if (mCallbacks.contains(callback) == false) {                    mCallbacks.add(callback);                }            }        }

        @Override        public void removeCallback(Callback callback) {            synchronized (mCallbacks) {                mCallbacks.remove(callback);            }        }

        @Override        public void setFixedSize(int width, int height) {            if (mRequestedWidth != width || mRequestedHeight != height) {                mRequestedWidth = width;                mRequestedHeight = height;                requestLayout();            }        }

        @Override        public void setSizeFromLayout() {            if (mRequestedWidth != -1 || mRequestedHeight != -1) {                mRequestedWidth = mRequestedHeight = -1;                requestLayout();            }        }

        @Override        public void setFormat(int format) {            // for backward compatibility reason, OPAQUE always            // means 565 for SurfaceView            if (format == PixelFormat.OPAQUE)                format = PixelFormat.RGB_565;

            mRequestedFormat = format;            if (mSurfaceControl != null) {                updateSurface();            }        }

        /**         * @deprecated setType is now ignored.         */        @Override        @Deprecated        public void setType(int type) { }

        @Override        public void setKeepScreenOn(boolean screenOn) {            runOnUiThread(() -> SurfaceView.this.setKeepScreenOn(screenOn));        }

        /**         * Gets a {@link Canvas} for drawing into the SurfaceView's Surface         *         * After drawing into the provided {@link Canvas}, the caller must         * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface.         *         * The caller must redraw the entire surface.         * @return A canvas for drawing into the surface.         */

         //封装的锁Canvas        @Override        public Canvas lockCanvas() {            return internalLockCanvas(null, false);        }

        /**         * Gets a {@link Canvas} for drawing into the SurfaceView's Surface         *         * After drawing into the provided {@link Canvas}, the caller must         * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface.         *         * @param inOutDirty A rectangle that represents the dirty region that the caller wants         * to redraw.  This function may choose to expand the dirty rectangle if for example         * the surface has been resized or if the previous contents of the surface were         * not available.  The caller must redraw the entire dirty region as represented         * by the contents of the inOutDirty rectangle upon return from this function.         * The caller may also pass null instead, in the case where the         * entire surface should be redrawn.         * @return A canvas for drawing into the surface.         */        @Override        public Canvas lockCanvas(Rect inOutDirty) {            return internalLockCanvas(inOutDirty, false);        }

        @Override        public Canvas lockHardwareCanvas() {            return internalLockCanvas(null, true);        }

         //内部锁画布        private Canvas internalLockCanvas(Rect dirty, boolean hardware) {            mSurfaceLock.lock();

            if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " " + "Locking canvas... stopped="                    + mDrawingStopped + ", surfaceControl=" + mSurfaceControl);

            Canvas c = null;            if (!mDrawingStopped && mSurfaceControl != null) {                try {                    //最终是锁住持有的surface的canvas,上面说的surface的lockcanvas是jni方法                    if (hardware) {

                        c = mSurface.lockHardwareCanvas();                    } else {                        c = mSurface.lockCanvas(dirty);                    }                } catch (Exception e) {                    Log.e(LOG_TAG, "Exception locking surface", e);                }            }

            if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " " + "Returned canvas: " + c);            if (c != null) {                mLastLockTime = SystemClock.uptimeMillis();                return c;            }

            // If the Surface is not ready to be drawn, then return null,            // but throttle calls to this function so it isn't called more            // than every 100ms.            long now = SystemClock.uptimeMillis();            long nextTime = mLastLockTime + 100;            if (nextTime > now) {                try {                    Thread.sleep(nextTime-now);                } catch (InterruptedException e) {                }                now = SystemClock.uptimeMillis();            }            mLastLockTime = now;            mSurfaceLock.unlock();

            return null;        }

        /**         * Posts the new contents of the {@link Canvas} to the surface and         * releases the {@link Canvas}.         *         * @param canvas The canvas previously obtained from {@link #lockCanvas}.         */

         //封装的解锁canvas,实际也是调用Surafce的解锁canvas        @Override        public void unlockCanvasAndPost(Canvas canvas) {            mSurface.unlockCanvasAndPost(canvas);            mSurfaceLock.unlock();        }        //获取当前持有的 surface        @Override        public Surface getSurface() {            return mSurface;        }

        @Override        public Rect getSurfaceFrame() {            return mSurfaceFrame;        }    };

}    ...otherCodes复制代码



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有